<script setup lang="ts">
import { ref, computed, reactive } from 'vue'
import JsonHighlightTree from './JsonHighlightTree.vue'

interface JsonNode {
  key?: string
  value: any
  type: 'object' | 'array' | 'string' | 'number' | 'boolean' | 'null'
  collapsed?: boolean
  path: string
}

const input = ref('')
const result = ref('')
const showResult = ref(false)
const isError = ref(false)
const parsedJson = ref<JsonNode | null>(null)

// 颜色配置
const colorScheme = reactive({
  key: '#0066cc',        // 键名 - 蓝色
  string: '#22c55e',     // 字符串 - 绿色
  number: '#a855f7',     // 数字 - 紫色
  boolean: '#f97316',    // 布尔值 - 橙色
  null: '#6b7280',       // null - 灰色
  bracket: '#374151',    // 括号 - 深灰色
  punctuation: '#374151' // 标点符号 - 深灰色
})

// 深色模式颜色配置
const darkColorScheme = reactive({
  key: '#60a5fa',        // 键名 - 浅蓝色
  string: '#4ade80',     // 字符串 - 浅绿色
  number: '#c084fc',     // 数字 - 浅紫色
  boolean: '#fb923c',    // 布尔值 - 浅橙色
  null: '#9ca3af',       // null - 浅灰色
  bracket: '#d1d5db',    // 括号 - 浅灰色
  punctuation: '#d1d5db' // 标点符号 - 浅灰色
})

// 获取当前颜色方案
const currentColors = computed(() => {
  return document.documentElement.classList.contains('dark') ? darkColorScheme : colorScheme
})

function parseJsonToTree(obj: any, path = ''): JsonNode {
  const getType = (val: any): JsonNode['type'] => {
    if (val === null) return 'null'
    if (Array.isArray(val)) return 'array'
    if (typeof val === 'object') return 'object'
    return typeof val as JsonNode['type']
  }

  const node: JsonNode = {
    value: obj,
    type: getType(obj),
    path,
    collapsed: false
  }

  return node
}

function formatJson() {
  try {
    if (!input.value.trim()) {
      throw new Error('请输入JSON数据')
    }
    const obj = JSON.parse(input.value)
    parsedJson.value = parseJsonToTree(obj)
    result.value = JSON.stringify(obj, null, 2)
    showResult.value = true
    isError.value = false
  } catch (e: any) {
    result.value = `JSON 格式错误: ${e?.message || '未知错误'}`
    showResult.value = true
    isError.value = true
    parsedJson.value = null
  }
}

function minifyJson() {
  try {
    if (!input.value.trim()) {
      throw new Error('请输入JSON数据')
    }
    const obj = JSON.parse(input.value)
    result.value = JSON.stringify(obj)
    showResult.value = true
    isError.value = false
    parsedJson.value = null
  } catch (e: any) {
    result.value = `JSON 格式错误: ${e?.message || '未知错误'}`
    showResult.value = true
    isError.value = true
    parsedJson.value = null
  }
}

function validateJson() {
  try {
    if (!input.value.trim()) {
      throw new Error('请输入JSON数据')
    }
    JSON.parse(input.value)
    result.value = '✅ JSON 格式正确！'
    showResult.value = true
    isError.value = false
    parsedJson.value = null
  } catch (e: any) {
    result.value = `❌ JSON 格式错误: ${e?.message || '未知错误'}`
    showResult.value = true
    isError.value = true
    parsedJson.value = null
  }
}

async function copyJson() {
  try {
    const textToCopy = showResult.value && result.value ? result.value : input.value
    if (navigator.clipboard && navigator.clipboard.writeText) {
      await navigator.clipboard.writeText(textToCopy)
    } else {
      // 降级处理：创建临时文本区域
      const textArea = document.createElement('textarea')
      textArea.value = textToCopy
      document.body.appendChild(textArea)
      textArea.select()
      document.execCommand('copy')
      document.body.removeChild(textArea)
    }
  } catch (error) {
    console.warn('复制失败:', error)
  }
}

function clearAll() {
  input.value = ''
  result.value = ''
  showResult.value = false
  isError.value = false
  parsedJson.value = null
}

// 语法高亮渲染
function renderJsonValue(value: any, indent = 0): string {
  const indentStr = '  '.repeat(indent)
  const colors = currentColors.value

  if (value === null) {
    return `<span style="color: ${colors.null}">null</span>`
  }

  if (typeof value === 'string') {
    return `<span style="color: ${colors.string}">"${value}"</span>`
  }

  if (typeof value === 'number') {
    return `<span style="color: ${colors.number}">${value}</span>`
  }

  if (typeof value === 'boolean') {
    return `<span style="color: ${colors.boolean}">${value}</span>`
  }

  if (Array.isArray(value)) {
    if (value.length === 0) {
      return `<span style="color: ${colors.bracket}">[]</span>`
    }

    const items = value.map((item, index) => {
      const comma = index < value.length - 1 ? ',' : ''
      return `${indentStr}  ${renderJsonValue(item, indent + 1)}<span style="color: ${colors.punctuation}">${comma}</span>`
    }).join('\n')

    return `<span style="color: ${colors.bracket}">[</span>\n${items}\n${indentStr}<span style="color: ${colors.bracket}">]</span>`
  }

  if (typeof value === 'object') {
    const keys = Object.keys(value)
    if (keys.length === 0) {
      return `<span style="color: ${colors.bracket}">{}</span>`
    }

    const items = keys.map((key, index) => {
      const comma = index < keys.length - 1 ? ',' : ''
      return `${indentStr}  <span style="color: ${colors.key}">"${key}"</span><span style="color: ${colors.punctuation}">: </span>${renderJsonValue(value[key], indent + 1)}<span style="color: ${colors.punctuation}">${comma}</span>`
    }).join('\n')

    return `<span style="color: ${colors.bracket}">{</span>\n${items}\n${indentStr}<span style="color: ${colors.bracket}">}</span>`
  }

  return String(value)
}

// 示例JSON数据
function loadExample() {
  input.value = JSON.stringify({
    "name": "工具集合",
    "version": "1.0.0",
    "features": [
      "JSON格式化",
      "语法高亮",
      "折叠展开"
    ],
    "config": {
      "theme": "auto",
      "indentSize": 2,
      "showLineNumbers": true
    },
    "stats": {
      "users": 1000,
      "rating": 4.8,
      "active": true,
      "lastUpdate": null
    }
  }, null, 2)
}
</script>

<template>
  <div class="space-y-4">
    <!-- 工具栏 -->
    <div class="flex flex-wrap gap-2">
      <button @click="formatJson" data-testid="format-btn" class="px-3 py-1 bg-primary text-white rounded hover:bg-primary/90 transition-colors">
        <i class="fa fa-indent mr-1"></i> 格式化
      </button>
      <button @click="minifyJson" data-testid="minify-btn" class="px-3 py-1 bg-gray-600 text-white rounded hover:bg-gray-700 transition-colors">
        <i class="fa fa-compress mr-1"></i> 压缩
      </button>
      <button @click="validateJson" data-testid="validate-btn" class="px-3 py-1 bg-secondary text-white rounded hover:bg-secondary/90 transition-colors">
        <i class="fa fa-check mr-1"></i> 验证
      </button>
      <button @click="copyJson" data-testid="copy-btn" class="px-3 py-1 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors">
        <i class="fa fa-copy mr-1"></i> 复制
      </button>
      <button @click="loadExample" data-testid="example-btn" class="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors">
        <i class="fa fa-file-code-o mr-1"></i> 示例
      </button>
      <button @click="clearAll" data-testid="clear-btn" class="px-3 py-1 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors">
        <i class="fa fa-trash mr-1"></i> 清空
      </button>
    </div>

    <!-- 输入区域 -->
    <div>
      <label class="block text-sm font-medium mb-2 text-gray-700 dark:text-gray-300">
        <i class="fa fa-edit mr-1"></i> JSON数据输入：
      </label>
      <textarea
        v-model="input"
        data-testid="json-input"
        class="w-full h-60 p-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary/50 resize-none font-mono text-sm transition-colors"
        placeholder='输入JSON数据，例如：{"name":"工具集合","version":"1.0"}'
      ></textarea>
    </div>

    <!-- 结果显示区域 -->
    <div v-if="showResult">
      <div class="flex items-center justify-between mb-2">
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
          <i class="fa fa-eye mr-1"></i> 格式化结果：
        </label>
      </div>
      
      <!-- 错误显示 -->
      <div v-if="isError" class="p-4 rounded-lg bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800">
        <div class="flex items-center mb-2">
          <i class="fa fa-exclamation-triangle text-red-500 mr-2"></i>
          <span class="font-medium text-red-700 dark:text-red-300">JSON解析错误</span>
        </div>
        <pre class="text-red-600 dark:text-red-400 font-mono text-sm whitespace-pre-wrap">{{ result }}</pre>
      </div>

      <!-- 成功结果显示 -->
      <div v-else class="border border-gray-200 dark:border-gray-600 rounded-lg overflow-hidden">
        <!-- 格式化JSON显示（整合高亮、格式化和可折叠功能） -->
        <JsonHighlightTree 
          v-if="parsedJson !== null"
          data-testid="json-highlight-tree"
          :data="parsedJson.value"
          :colorScheme="currentColors"
          :maxDepth="10"
          class="bg-white dark:bg-gray-900 p-3 rounded border max-h-96 overflow-y-auto"
        />

        <!-- 普通文本显示（用于压缩和验证结果） -->
        <div v-else class="bg-white dark:bg-gray-800 p-4">
          <div class="flex items-center mb-3">
            <span class="text-sm font-medium text-gray-600 dark:text-gray-400">
              <i class="fa fa-file-text-o mr-1"></i> 结果显示
            </span>
          </div>
          <pre class="font-mono text-sm overflow-x-auto text-gray-900 dark:text-gray-100 bg-gray-50 dark:bg-gray-900 p-3 rounded border border-gray-200 dark:border-gray-700 max-h-96 overflow-y-auto">{{ result }}</pre>
        </div>
      </div>
    </div>

    <!-- 使用说明 -->
    <div class="bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
      <h3 class="font-medium text-blue-800 dark:text-blue-200 mb-2">
        <i class="fa fa-info-circle mr-1"></i> 功能说明
      </h3>
      <ul class="text-sm text-blue-700 dark:text-blue-300 space-y-1">
        <li><strong>格式化：</strong> 美化JSON格式，同时提供语法高亮、颜色区分和可折叠功能</li>
        <li><strong>压缩：</strong> 移除所有空格和换行，生成紧凑格式</li>
        <li><strong>验证：</strong> 检查JSON语法是否正确</li>
        <li><strong>复制：</strong> 一键复制格式化结果到剪贴板</li>
        <li><strong>示例：</strong> 加载示例数据快速体验功能</li>
        <li><strong>交互式浏览：</strong> 支持折叠/展开的JSON结构浏览，语法高亮显示</li>
      </ul>
    </div>
  </div>
</template>

<style scoped>
/* 确保语法高亮在深色模式下正确显示 */
.dark pre {
  color-scheme: dark;
}

/* 复制按钮成功状态 */
.bg-green-500 {
  background-color: #10b981 !important;
}

/* 滚动条样式 */
.max-h-96::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.max-h-96::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.1);
  border-radius: 4px;
}

.max-h-96::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 4px;
}

.max-h-96::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 0, 0, 0.5);
}

.dark .max-h-96::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.1);
}

.dark .max-h-96::-webkit-scrollbar-thumb {
  background: rgba(75, 85, 99, 0.5);
}

.dark .max-h-96::-webkit-scrollbar-thumb:hover {
  background: rgba(75, 85, 99, 0.7);
}
</style>